module('lgx.utils', package.seeall)
PATHSEP = string.find(os.getenv('PATH'), '/') and '/' or '\\'
function concatpath(pre,etc)
    local endchar = pre[#pre]
    if endchar==PATHSEP then
        return pre..etc
    else
        return pre..PATHSEP..etc
    end
end

function template(templ, repmap)
    local s,n = string.gsub(templ, '$[(][^)]+[)]', repmap)
    return s
end

function issamecode(path, code)
    local file = io.open(path, 'r')
    if not file then return false end
    local fcode = file:read('*a')
    file:close()
    return fcode == code
end

function checkwrite(fc, path, code)
     if not issamecode(path, code) then
        local file = io.open(path, 'w')
        if not file then
            fc:clean()
            error('create '..path..' failed!', 2)
        end
        file:write(code)
        file:close()
        print(string.format('writing "%s" (OK)', path))
    else   
        print(string.format('writing "%s" (SKIP)', path))
	end
    fc:keep(path)
end

function tostringx(value)
    if type(value) == 'string' then
        return "'"..string.gsub(value, '([\'|"|\\])', '\\%1').."'"
    else
        return tostring(value)
    end
end

function dump(value, key, tab)
    local fmt = ''
    if type(key) == 'string' then
        fmt = "['%s']=%s"
        key = string.gsub(key, '([\'|"|\\])', '\\%1') 
    else
        fmt = "[%d]=%s"
    end
    if type(value) == 'table' then
        local code = {}
        for k,v in pairs(value) do
            dump(v, k, code)
        end
        for i,v in ipairs(value) do
            dump(v, k, code)
        end
        str = '{'..table.concat(code, ',')..'}'

        if key and tab then
            table.insert(tab, string.format(fmt, key, str))
        else
            return str
        end
    elseif key and tab then
        table.insert(tab, string.format(fmt, key, tostringx(value)))
    else
        return tostringx(value)
    end
end

filecleaner = {}
filecleaner.__index = filecleaner

local FCCONFIG = 'fcconfig.luagccxml'
function filecleaner.new(path)
    local o = {path=path}
    o.config = concatpath(path, FCCONFIG)

    --load old file list
    local file = io.open(o.config, 'r')
    if not file then
        o.oldlist = {}
    else
        o.oldlist = loadstring('return '..file:read('*a'))()
        file:close()
    end

    o.newlist = {}
    setmetatable(o, filecleaner)
    return o
end

function filecleaner:keep(fname)
    self.newlist[fname] = true
end

function filecleaner:clean()
    --clean file
    for k,v in pairs(self.oldlist) do
        if not self.newlist[k] then
            os.remove(k)
            print('deleted "'..k..'" (OK)')
        end
    end
    --save newlist
    local file = io.open(self.config, 'w')
    if not file then error('can not open '..self.config..' for write.', 2) end
    file:write(dump(self.newlist))
    file:close()
end
